package core

import (
	"github.com/Unixeno/TheMoon/logging"
	"github.com/Unixeno/TheMoon/moon/core/context"
	"github.com/Unixeno/TheMoon/moon/core/module"
	"github.com/Unixeno/TheMoon/moon/probe"
	"github.com/Unixeno/TheMoon/moon/ssh"
	"github.com/Unixeno/TheMoon/moon/starlink"
	"github.com/Unixeno/TheMoon/moon/zone"
	"os"
	"os/signal"
	"syscall"
)

var logger = logging.GetLogger("core")
var modules []module.Module

func Init() {
	logger.Debug("init core")
	modules = []module.Module{
		zone.GetModule(),
		probe.GetModule(),
		ssh.GetModule(),
	}
}

func Run() {
	startServe()
	gracefulShutdown()
}

func startServe() {
	logger.Debug("start core")

	client, err := starlink.GetClient()
	if err != nil {
		logger.WithError(err).Error("failed to create client")
		os.Exit(1)
	}
	context.InitContext()

	context.RegisterClient(client)

	for _, m := range modules {
		m.Init()
		m.Start()
	}
}

func gracefulShutdown() {
	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM,
		syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT)
	select {
	case <-context.Done():
		logger.Info("global context canceled, exit...")
	case s := <-c:
		logger.Infof("get signal %v", s.String())
		context.Cancel()
	}
}
